package org.roulette.model;

import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "game")
@XmlAccessorType(XmlAccessType.FIELD)
public final class Game {
	private int tableCounter = 0;
	private int counter = 0;

	@XmlElement
	private static ArrayList<Table> tableList = new ArrayList<Table>();
	private static ArrayList<Player> playerList = new ArrayList<Player>();
	private static final Game INSTANCE = new Game();

	private Game() {
		if (INSTANCE != null) {
			throw new IllegalStateException("Already instantiated");
		}
	}

	public static Game getInstance() {
		return INSTANCE;
	}

	public static List<Table> getTableList() {
		return tableList;
	}

	public int getCounter() {
		return counter;
	}

	public void setCounter(int counter) {
		for (Table t : tableList) {
			t.setCounter(counter);
		}
	}

	public static Table getTableById(int id) {
		Table table = null;
		for (Table t : tableList) {
			if (t.getId() == id) {
				table = t;
			}
		}
		return table;
	}

	public Table addTableToGame() {
		Table table = new Table(tableCounter++);
		tableList.add(table);
		return table;
	}

	public ArrayList<Player> getPlayerList() {
		return playerList;
	}

	public static boolean addPlayer(Player player) {
		boolean userAlreadyExists = false;
		for (Player p : playerList) {
			if (p.getName().equals(player.getName())) {
				userAlreadyExists = true;
			}
		}
		if (!userAlreadyExists) {
			playerList.add(player);
		}
		return userAlreadyExists;
	}

	public static Table getTableByPlayer(String player) {
		Table currentTable = null;
		for (Table table : tableList) {
			if (table.getPlayerByName(player) != null) {
				currentTable = table;
			}
		}
		return currentTable;
	}

	public static void betOnTable(String name, String betField, int betValue) {
		if (doesPlayerExist(name)) {
			Table table = getTableByPlayer(name);
			Field field = table.getBetField(Integer.parseInt(betField));
			Player player = table.getPlayerByName(name);
			if ((player.getStack() - Math.abs(betValue)) >= 0) {
				player.setStack(player.getStack() - Math.abs(betValue));
				Bet bet = new Bet(Math.abs(betValue), name);
				table.setBet(player, field, bet);
			} else if(player.getStack()>0){
				Bet bet = new Bet(player.getStack(), name);
				player.setStack(0);
				table.setBet(player, field, bet);
			}
		}
	}

	public static boolean doesPlayerExist(String name) {
		boolean userAlreadyExists = false;
		for (Player p : playerList) {
			if (p.getName().equals(name)) {
				userAlreadyExists = true;
			}
		}
		return userAlreadyExists;
	}

	public boolean doesPlayerExist(Player player) {
		boolean userAlreadyExists = false;
		for (Player p : playerList) {
			if (p.getName().equals(player.getName())) {
				userAlreadyExists = true;
			}
		}
		return userAlreadyExists;
	}

	public boolean doesTableExist(String tableId) {
		boolean tableAlreadyExists = false;
		for (Table t : tableList) {
			if (t.getId() == Integer.parseInt(tableId)) {
				tableAlreadyExists = true;
			}
		}
		return tableAlreadyExists;
	}

	public Table getTable(String tableId) {
		Table table = null;
		for (Table t : tableList) {
			if (t.getId() == Integer.parseInt(tableId)) {
				table = t;
			}
		}
		return table;
	}

	public static Player getPlayerByTableId(int parseInt, String playerName) {
		Table table = getTableById(parseInt);
		return table.getPlayerByName(playerName);
	}

	public static boolean checkLogin(String playerName, String password) {
		for (Player p : playerList) {
			if (p.getName().equals(playerName)
					&& p.getPasswordHash().equals(password)) {
				return true;
			}
		}
		return false;
	}

	public static Player getPlayer(String playerName) {
		Player player = null;
		for (Player p : playerList) {
			if (p.getName().equals(playerName)) {
				player = p;
			}
		}
		return player;
	}

	public static void removePlayerFromTable(String player) {
		for (Table table : tableList) {
			table.removePlayerFromTable(table.getPlayerByName(player));
		}
	}

}
